home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Games of Daze
/
Infomagic - Games of Daze (Summer 1995) (Disc 1 of 2).iso
/
x2ftp
/
msdos
/
libs
/
knowhow4
/
ask_man.cpp
< prev
next >
Wrap
C/C++ Source or Header
|
1994-10-10
|
20KB
|
725 lines
#include "stdlib.h"
#include "ask_man.h"
#include <dos.h>
int indexNo;
////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
KH_AskManager::KH_AskManager(char** tableNames, KH_QUERRY** querries, int num)
{
unlink("answer.db");
unlink("answer1.db");
querryList = querries;
workTable = NULL;
answerTable = NULL;
numberOfTables = num;
tables = (KH_PXTable**)malloc(num * sizeof(KH_PXTable**));
for(int i = 0; i < num; i++)
tables[i] = new KH_PXTable(tableNames[i]);
}
/////////////////////////////////
KH_AskManager::~KH_AskManager()
{
for(int i = 0; i < numberOfTables; i++)
delete tables[i];
delete tables;
delete answerTable;
delete workTable;
}
/////////////////////////////////
int KH_AskManager::createAnswerTable(int nOT)
{
pxErr = PXTblDelete("answer.db");
KH_STRTABLE* fields = new KH_STRTABLE(0, NULL);
KH_STRTABLE* types = new KH_STRTABLE(0, NULL);
int dupNo; // Number of duplicated fields
int dupLen; // Len of addition to fld name (if duplicated)
char dupBuf[10]; // Buffer for name addition (if duplicated)
char fld[26];
for(int i = 0; i < nOT; i++)
{
for(int j = 1; j <= tables[i]->nFlds; j++)
{
PXFldName(tables[i]->tblHandle, j, 26, fld);
fields->add(fld);
char typ[26];
PXFldType(tables[i]->tblHandle, j, 26, typ);
types->add(typ);
}
}
//////////////// Test for duplicated field names ////////////////////
for(i = 0; i < fields->used; i++)
{
dupNo = 0;
for(int j = i + 1; j < fields->used; j++)
{
if(!strcmp((*fields)[i], (*fields)[j]))
dupNo++;
else
continue;
if(dupNo != 0)
{
int l = strlen((*fields)[j]);
dupLen = strlen(itoa(dupNo, dupBuf, 10));
fields->strings[j] = (char*)realloc(fields->strings[j],
l + dupLen + 1);
strcpy(fields->strings[j] + l, dupBuf);
fields->strings[j][l + dupLen] = '\0';
}
}
}
//////////////////////// End of duplication test /////////////////////////
if((pxErr = PXTblCreate("answer.db", fields->used, fields->strings,
types->strings)) != PXSUCCESS)
{
delete fields;
delete types;
return 0;
}
delete fields;
delete types;
return 1;
}
/////////////////////////////////
int KH_AskManager::checkQuerry()
{
int totalCheckers = 0;
/* First of all we check the number of checked or calculated fields
in the querry. Querry with no checked fields is invalid.
*/
for(int i = 0; i < numberOfTables; i++)
for(int j = 1; j <= tables[i]->nFlds; j++)
{
if(querryList[i]->checkedFields[j] != QFREE)
{
totalCheckers++;
break;
}
}
if(!totalCheckers)
{
khPxErr = 1;
return 0;
}
/* Then we iterates EXAMPLES.
Second table MUST contain common variable(s)
with 1-st, third - with the 1-st or 2-nd and so on. If this
condition fails, querry fails too, because one of tables is not
linked with others.
*/
if(numberOfTables == 1)
return 1;
for(i = 1; i < numberOfTables; i++)
for(int k = 0; k < querryList[i]->examples->used; k++)
for(int j = 0; j < i; j++)
for(int l = 0; l < querryList[j]->examples->used; l++)
if(!strcmp((*(querryList[j]->examples))[l],
(*(querryList[i]->examples))[k]))
return 1;
khPxErr = 2;
return 0;
}
/////////////////////////////////
KH_STRTABLE* KH_AskManager::makeQuerry(int n)
{
KH_STRTABLE* retQuerry = new KH_STRTABLE(0, NULL);
int qnum = 0;
for(int i = 0; i < tables[n]->nFlds; i++)
if(querryList[n]->querryNumbers[0] != NULL
&& querryList[n]->querryNumbers[qnum] == i)
{
retQuerry->add((*(querryList[n]->querry))[qnum]);
qnum++;
}
else
retQuerry->add("");
return retQuerry;
}
/////////////////////////////////
int KH_AskManager::processSingleTable()
{
KH_STRTABLE* completeQuerry = makeQuerry(0);
int result;
KH_PXFLD* ret;
int r = 0;
while(result = tables[0]->Find(completeQuerry->strings))
{
pxErr = PXRecBufCopy(tables[0]->recHandle, answerTable->recHandle);
if((pxErr = PXRecAppend(answerTable->tblHandle, answerTable->recHandle))
!= PXSUCCESS)
break;
r = 1;
if(result == 2)
break;
}
delete completeQuerry;
return r;
}
/////////////////////////////////
KH_STRTABLE* KH_AskManager::getCurrExamples(int n)
{
KH_STRTABLE* ret = new KH_STRTABLE(0, NULL);
int eNum = 0;
for(int j = 0; j < tables[n]->nFlds; j++)
{
if(querryList[n]->exampleNumbers[eNum] == j)
ret->add((*(querryList[n]->examples))[eNum]);
else
ret->add("");
}
return ret;
}
/////////////////////////////////
KH_STRTABLE* KH_AskManager::getExamples(int n)
{
KH_STRTABLE* ret = new KH_STRTABLE(0, NULL);
int eNum = 0;
for(int i = 0; i < n; i++)
for(int j = 0; j < tables[i]->nFlds; j++)
{
if(querryList[i]->exampleNumbers[eNum] == j)
ret->add((*(querryList[i]->examples))[eNum]);
else
ret->add("");
}
return ret;
}
/////////////////////////////////
int KH_AskManager::getExSrc(KH_STRTABLE* ex, KH_STRTABLE* cur, int* eNums,
FIELDHANDLE* exFlds)
{
int k = 0;
for(int i = 0; i < cur->used; i++)
for(int j = 0; j < ex->used; j++)
{
if((*ex)[j][0] == '\0'
|| strcmp((*ex)[j], ((*cur)[i])))
continue;
eNums[k] = i + 1;
eNums[k + 1] = j + 1;
exFlds[k / 2] = j + 1;
k += 2;
}
return k;
}
/////////////////////////////////
int KH_AskManager::moveToRec(int* eNums, int numEx, int n, int mode,
FIELDHANDLE compSecIndexHandle)
{
char fieldType[20];
char _fieldType[20];
RECORDHANDLE rch;
pxErr = PXRecBufOpen(workTable->tblHandle, &rch);
for(int i = 0; i < numEx; i += 2)
{
pxErr = PXFldType(workTable->tblHandle, eNums[i + 1], 20,
fieldType);
pxErr = PXFldType(tables[n]->tblHandle, eNums[i], 20,
_fieldType);
if(fieldType[0] != _fieldType[0])
{
khPxErr = 3;
pxErr = PXRecBufClose(rch);
return 0;
}
switch(fieldType[0])
{
case 'A':
char buf1[255];
pxErr = PXGetAlpha(tables[n]->recHandle, eNums[i],
255, buf1);
pxErr = PXPutAlpha(rch, eNums[i + 1], buf1);
break;
case 'N':
double d1;
pxErr = PXGetDoub(tables[n]->recHandle, eNums[i], &d1);
pxErr = PXPutDoub(rch, eNums[i + 1], d1);
break;
case 'S':
short sh1;
pxErr = PXGetShort(tables[n]->recHandle, eNums[i], &sh1);
pxErr = PXPutShort(rch, eNums[i + 1], sh1);
break;
case 'D':
long date1;
pxErr = PXGetDate(tables[n]->recHandle, eNums[i], &date1);
pxErr = PXPutDate(rch, eNums[i + 1], date1);
break;
default:
break;
}
}
if((pxErr = PXSrchFld(workTable->tblHandle, rch, compSecIndexHandle, mode))
!= PXSUCCESS)
{
pxErr = PXRecBufClose(rch);
return 0;
}
pxErr = PXRecBufClose(rch);
return 1;
}
////////////////////////////
void KH_AskManager::writeField(KH_PXTable* srcTable, KH_PXTable* destTable)
{
BLOBHANDLE srcBlob;
BLOBHANDLE destBlob;
unsigned long size;
unsigned int workSize;
pxErr = PXBlobOpenRead(srcTable->recHandle, srcTable->fldHandle, &srcBlob);
pxErr = PXBlobGetSize(srcBlob, &size);
pxErr = PXBlobOpenWrite(destTable->recHandle, destTable->fldHandle,
&srcBlob, size, PXBLOBNEW);
if(size > 65520)
workSize = 65520;
else
workSize = size;
char* buff = new char[workSize];
for(long off = 0; off + workSize <= size; off += workSize)
{
pxErr = PXBlobGet(srcBlob, workSize, off, buff);
pxErr = PXBlobPut(destBlob, workSize, off, buff);
if(size - off > 65520)
workSize = 65520;
else
workSize = size;
}
pxErr = PXBlobClose(srcBlob, PXBLOBREJECT);
pxErr = PXBlobClose(destBlob, PXBLOBACCEPT);
delete buff;
}
////////////////////////////
int KH_AskManager::processMultipleTables()
{
char buf[255]; // String field of KH_PXFLD structure
KH_PXFLD* retFld = new KH_PXFLD(buf);// Structure returned by getField in
// the process of ANSWER building
int eNums[510]; // EXAMPLES intersections
FIELDHANDLE exFlds[255];
for(int i = 1; i < numberOfTables; i++) // Sequential processing
{ // i == 1 <= we skip 0th table
KH_STRTABLE* ex = getExamples(i); // Examples in ANSWER
KH_STRTABLE* cur = getCurrExamples(i); // and in current table
int numEx;
if(!(numEx = getExSrc(ex, cur, eNums, exFlds)))// eNums contains pares:
{ // field No of workTable and of
delete retFld; // tables[i] containing examples with
delete cur; // same names. NumEx is 0 if no
delete ex; // intersections find (error), or
return 0; // 2 * number of examples on success.
} // exFlds contains ANSWER EX index flds
delete answerTable; // Old ANSWER will be replaced
delete workTable;
pxErr = PXTblRename("answer.db", "answer1.db");
char nm[10];
itoa(indexNo, nm, 10);
indexNo++;
FIELDHANDLE compSecIndexHandle;
pxErr = PXKeyMap("answer1.db", numEx / 2, exFlds, nm, 0,
&compSecIndexHandle);
exFlds[0] = compSecIndexHandle;
pxErr = PXKeyAdd("answer1.db", 1, exFlds, SECONDARY);
if(!createAnswerTable(i + 1)) // Create new ANSWER table
{ // return on fail
delete retFld;
delete cur;
delete ex;
return 0;
}
answerTable = new KH_PXTable("answer.db"); // Build new temp. tables
workTable = new KH_PXTable("answer1.db", compSecIndexHandle);
KH_STRTABLE* completeQuerry = makeQuerry(i); // Unpacked querry
RECORDNUMBER recNumber;
pxErr = PXRecFirst(tables[i]->tblHandle);
while((pxErr = PXRecGet(tables[i]->tblHandle, tables[i]->recHandle))
== PXSUCCESS)
{
int mode = SEARCHFIRST;
pxErr = PXRecFirst(workTable->tblHandle);
while(moveToRec(eNums, numEx, i, mode, compSecIndexHandle)
&& (pxErr = PXRecGet(workTable->tblHandle,
workTable->recHandle) == PXSUCCESS))
{
mode = SEARCHNEXT;
if(!tables[i]->testQuerry(completeQuerry->strings))
break;
for(int number = 1; number <= workTable->nFlds; number++)
{
workTable->setFld(number);
answerTable->setFld(number);
if(workTable->getField(retFld) == KH_BLOB)
writeField(workTable, answerTable);
else
answerTable->putField(retFld);
}
for(int number1 = number, num = 1;
number1 <= number + tables[i]->nFlds; number1++, num++)
{
tables[i]->setFld(num);
answerTable->setFld(number1);
if(tables[i]->getField(retFld) == KH_BLOB)
writeField(tables[i], answerTable);
else
answerTable->putField(retFld);
}
if((pxErr = PXRecAppend(answerTable->tblHandle,
answerTable->recHandle))
!= PXSUCCESS)
{
delete retFld;
delete completeQuerry;
delete cur;
delete ex;
return 0;
}
}
if((pxErr = PXRecNext(tables[i]->tblHandle)) != PXSUCCESS)
break;
}
delete completeQuerry;
delete cur;
delete ex;
}
delete retFld;
return 1;
}
/////////////////////////////////
void KH_AskManager::dumpAnswer()
{
char buf[255]; // String field of KH_PXFLD structure
KH_PXFLD* retFld = new KH_PXFLD(buf);
delete workTable;
pxErr = PXTblDelete("answer1.db");
KH_STRTABLE* fields = new KH_STRTABLE(0, NULL);
KH_STRTABLE* types = new KH_STRTABLE(0, NULL);
int srcNo = 1;
char fld[26];
char typ[26];
for(int i = 0; i < numberOfTables; i++)
{
for(int j = 1; j <= tables[i]->nFlds; j++)
{
if(querryList[i]->checkedFields[j] != '\0')
{
PXFldName(answerTable->tblHandle, srcNo, 26, fld);
fields->add(fld);
PXFldType(answerTable->tblHandle, srcNo, 26, typ);
types->add(typ);
srcNo++;
}
}
}
workTable = new KH_PXTable("answer1.db", 0, fields->used,
fields->strings, types->strings);
pxErr = PXRecFirst(answerTable->tblHandle);
int fNo;
while((pxErr = PXRecGet(answerTable->tblHandle,
answerTable->recHandle)) == PXSUCCESS)
{
srcNo = fNo = 1;
for(i = 0; i < numberOfTables; i++)
{
for(int j = 1; j <= tables[i]->nFlds; j++)
{
if(querryList[i]->checkedFields[j] != '\0')
{
answerTable->setFld(srcNo);
workTable->setFld(fNo);
if(answerTable->getField(retFld) == KH_BLOB)
writeField(answerTable, workTable);
else
workTable->putField(retFld);
fNo++;
}
srcNo++;
}
}
pxErr = PXRecAppend(workTable->tblHandle, workTable->recHandle);
if((pxErr = PXRecNext(answerTable->tblHandle)) != PXSUCCESS)
break;
}
delete retFld;
delete fields;
delete types;
delete workTable;
delete answerTable;
pxErr = PXTblRename("answer1.db", "answer.db");
workTable = NULL;
answerTable = NULL;
}
/////////////////////////////////
int KH_AskManager::process()
{
if(!checkQuerry()) // Verification.
return 0;
if(!createAnswerTable(1)) // Create ANSWER table
return 0;
answerTable = new KH_PXTable("answer.db");
int ret = processSingleTable();
if(ret && numberOfTables > 1)
ret = processMultipleTables();
dumpAnswer();
return ret;
}
#include <iostream.h>
#include <time.h>
/////////////////////
/*
void main()
{
// Init PARADOX ENGINE
if(PXInit() != PXSUCCESS)
return;
// Process single-table querry to DEMO.DB table
char* tableNames[] = { "demo.db" }; // Table name
char* q[] = { "", "", "", "", "", "", "", "", "" }; // Querries
char* e[] = { "", "", "", "", "", "", "", "", "" }; // Examples
char* c = "\2\2\2\2\2\2\2\2\2\2\0"; // Checkers
KH_QUERRY* querry1 = new KH_QUERRY(q, e, c, 5); // Build querry
KH_QUERRY* querries[2]; // Querry list
querries[0] = querry1;
KH_AskManager* ask = new KH_AskManager(tableNames, querries, 1);
ask->process(); // Process querry, get ANSWER table
////////////
KH_PXTable table("answer.db");
char* shablon[] = { "", "", "", "", "", "", "", "", "", "", "" };
char buf[255];
int eot;
while(table.Find(shablon) == 1)
{
for(int i = 2; i < 5; i++)
{
table.setFld(i);
table.TranslateField(buf);
cout << buf << '\t';
}
cout << "\n";
}
delete ask;
delete querry1;
unlink("answer.db");
PXExit();
}
*/
void main()
{
// Init PARADOX ENGINE
if(PXInit() != PXSUCCESS)
return;
indexNo = 0; // ATTENTION !!! Absolutely necessary for multytable
// querries.
// Process single-table querry to DEMO.DB table
char* tableNames[] = { "demo.db", "demo.db", "demo.db" }; // Table name
char* q[] = { "", "", "", "", "", "", "", "", "" }; // Querries
char* e[] = { "", "", "X", "", "", "", "", "", "" }; // Examples
char* c = "\2\2\2\2\2\2\2\2\2\2\0"; // Checkers
KH_QUERRY* querry1 = new KH_QUERRY(q, e, c, 5); // Build querry
KH_QUERRY* querries[3]; // Querry list
querries[0] = querry1;
querries[1] = querry1;
querries[2] = querry1;
KH_AskManager* ask = new KH_AskManager(tableNames, querries, 3);
time_t first, second;
first = time(NULL);
ask->process(); // Process querry, get ANSWER table
second = time(NULL);
cout << "\nProcessing time = " << difftime(second,first) << " seconds \n";
////////////
KH_PXTable table("answer.db");
char* shablon[] = { "", "", "", "", "", "", "", "", "", "", "", "", "",
"", "", "", "", "", "", "", "", "", "", "", "", "" };
char buf[255];
int eot;
long l = 0;
while(table.Find(shablon) == 1)
{
for(int i = 1; i < 16; i++)
{
table.setFld(i);
table.TranslateField(buf);
cout << i << ": " << buf << "\n";
}
cout << "<<<<<<<<<<<<< RECORD " << l << " >>>>>>>>>>>>>>>>\n";
l++;
}
delete ask;
delete querry1;
unlink("answer.db");
PXExit();
}
/*
void main() // Add operations on BLOB fields
{
// Init PARADOX ENGINE
if(PXInit() != PXSUCCESS)
return;
// Process single-table querry to DEMO.DB table
char* tableNames[] = { "demo.db" }; // Table name
char* q[] = { "", "", "", "", "", "", "", "", "" }; // Querries
char* e[] = { "", "", "", "", "", "", "", "", "" }; // Examples
char* c = "\2\2\2\2\2\2\2\2\2\2\0"; // Checkers
KH_QUERRY* querry1 = new KH_QUERRY(q, e, c, 5); // Build querry
KH_QUERRY* querries[2]; // Querry list
querries[0] = querry1;
KH_AskManager* ask = new KH_AskManager(tableNames, querries, 1);
ask->process(); // Process querry, get ANSWER table
////////////
KH_PXTable table("answer.db");
char* shablon[] = { "", "", "", "", "", "", "", "", "", "", "" };
char buf[255];
char buf1[255];
int eot;
KH_PXFLD* retFld = new KH_PXFLD(buf1);
while(table.Find(shablon) == 1)
{
for(int i = 1; i < 6; i++)
{
table.setFld(i);
if(table.TranslateField(buf) == KH_BLOB)
{
table.getField(retFld);
cout << "***************** BLOB: " << retFld->str << "\n";
}
else
cout << buf << "\n";
}
cout << "<<<<<<<<<<<<<<<<<<<<<<<<\n";
}
delete retFld;
delete ask;
delete querry1;
unlink("answer.db");
PXExit();
}
*/
/*
void main()
{
// Init PARADOX ENGINE
if(PXInit() != PXSUCCESS)
return;
indexNo = 0; // ATTENTION !!! Absolutely necessary for multytable
// querries.
char buf1[255];
KH_PXFLD* retFld = new KH_PXFLD(buf1);
// Process single-table querry to DEMO.DB table
char* tableNames[] = { "demo.db", "demo.db", "demo.db" }; // Table name
char* q[] = { "", "", "", "", "", "", "", "", "" }; // Querries
char* e[] = { "", "", "X", "", "", "", "", "", "" }; // Examples
char* c = "\2\2\2\2\2\2\2\2\2\2\0"; // Checkers
KH_QUERRY* querry1 = new KH_QUERRY(q, e, c, 5); // Build querry
KH_QUERRY* querries[3]; // Querry list
querries[0] = querry1;
querries[1] = querry1;
querries[2] = querry1;
KH_AskManager* ask = new KH_AskManager(tableNames, querries, 3);
time_t first, second;
first = time(NULL);
ask->process(); // Process querry, get ANSWER table
second = time(NULL);
cout << "\nProcessing time = " << difftime(second,first) << " seconds \n";
////////////
KH_PXTable table("answer.db");
char* shablon[] = { "", "", "", "", "", "", "", "", "", "", "", "", "",
"", "", "", "", "", "", "", "", "", "", "", "", "" };
char buf[255];
int eot;
long l = 0;
while(table.Find(shablon) == 1)
{
for(int i = 1; i < 16; i++)
{
table.setFld(i);
if(table.TranslateField(buf) == KH_BLOB)
{
table.getField(retFld);
cout << "***************** BLOB: " << retFld->str << "\n";
}
else
cout << i << ": " << buf << "\n";
}
cout << "<<<<<<<<<<<<< RECORD " << l << " >>>>>>>>>>>>>>>>\n";
l++;
}
delete retFld;
delete ask;
delete querry1;
unlink("answer.db");
PXExit();
}
*/